<script lang="ts" setup>
/* eslint-disable @typescript-eslint/no-unused-vars */
import { addUnit, generateCssVars } from '@vc/utils';
import { type IconProps } from 'vc';
import { useRouterHelper } from 'vc/src/router';
import { useNamespace } from 'vc/src/use';
import type { PopoverProps } from 'vc/src/web/popover/types';
import { toF9 } from '@/utils';
import SearchContent from './search-content/index.vue';

interface SearchProps {
  /** 以下为 input 相关配置 参考 element */
  modelValue?: string | number;
  placeholder?: string;
  clearable?: boolean;
  suffixIcon?: IconProps;
  prefixIcon?: IconProps;
  clearIcon?: IconProps;
  /** input 框宽度 */
  width?: Numberish;
  /** input 获取焦点时的宽度 */
  focusWidth?: Numberish;
  /** input 框高度 */
  height?: Numberish;
  /** 是否需要 popover */
  hasPopover?: boolean;
  /** popover 相关配置 参考 element */
  popoverCfg?: PopoverProps;
}

const {
  modelValue = '',
  placeholder,
  clearable = true,
  suffixIcon = { icon: 'vi-sousuo', color: '#8B8C8C', cursor: true },
  prefixIcon,
  clearIcon,
  focusWidth,
  width = 200,
  height,
  hasPopover = true,
  popoverCfg = {
    'show-arrow': false,
    transition: 'vc-zoom-in-top',
    placement: 'bottom-start',
    'hide-after': 100,
    offset: 3,
    width: 500
  }
} = defineProps<SearchProps>();

const ns = /* hoist-static*/ useNamespace('search');

defineOptions({
  name: ns.b()
});

const emit = defineEmits(['update:modelValue', 'focus', 'enter', 'clear']);

// 节点的 ref
const popoverRef = ref();
const searchRef = ref();
const inputRef = ref();
// 内容的 class
const CONTENT_CLASS_NAME = ns.e('content');

const handleSuffixClick = () => {
  visible = false;
  useTimeoutFn(() => inputRef.value?.blur(), 100);
  emit('enter', modelValue);
};

let visible = $ref(false);

const { go } = useRouterHelper();

const handleFocus = () => {
  visible = true;
  emit('focus');
};

const inputStyle = computed(() => {
  function styleSet(attr) {
    return generateCssVars(
      {
        width: addUnit(attr)!,
        'focus-width': addUnit(attr)!
      },
      'input'
    );
  }

  return visible ? styleSet(focusWidth ?? width) : styleSet(width);
});

const handleInput = (value) => {
  emit('update:modelValue', value);
};

const handleClickOut = (e) => {
  if (!Array.from(e.target.classList).includes(CONTENT_CLASS_NAME)) {
    unref(popoverRef).popperRef?.delayHide?.();
    visible = false;
  }
};

const handleClear = () => {
  visible = false;
  useTimeoutFn(() => inputRef.value?.blur(), 100);
  emit('clear');
};

const handleSearch = (val) => {
  console.log(val, '===');
  handleClear();
  const { name, id } = val;
  emit('update:modelValue', name.replace(/<em>|<\/em>/g, ''));
  toF9(id);
};

const enterCount = ref(0);
const handleEnter = () => {
  visible = false;
  enterCount.value++;
  useTimeoutFn(() => inputRef.value?.blur(), 100);
  emit('enter', modelValue);
};
</script>

<template>
  <div ref="searchRef" v-click-outside="handleClickOut" :class="[ns.b()]">
    <vc-input ref="inputRef" v-bind="$props" @keydown.enter="handleEnter" :inputStyle="inputStyle" @input="handleInput" @suffixclick="handleSuffixClick" @focus="handleFocus" @clear="handleClear">
      <template v-if="$slots.prefix" #prefix>
        <slot name="prefix" />
      </template>
      <template v-if="$slots.suffix" #suffix>
        <slot name="suffix" />
      </template>
      <template v-if="$slots.prepend" #prepend>
        <slot name="prepend" />
      </template>
      <template v-if="$slots.append" #append>
        <slot name="append" />
      </template>
    </vc-input>
  </div>

  <vc-popover v-if="hasPopover" ref="popoverRef" v-bind="popoverCfg" :virtual-ref="searchRef" :visible="visible" virtual-triggering>
    <slot v-if="$slots.default" />
    <div v-else :class="[CONTENT_CLASS_NAME, 'text-black']">
      <search-content :keyword="modelValue" from="pageHeader" :enterCount="enterCount" v-model:visible="visible" @handleSearch="handleSearch" />
    </div>
  </vc-popover>
</template>

<style lang="scss" scoped>
:deep(.vc-input){
  .vc-input__wrapper {
    .vc-input__inner {
        padding: 0;
      }
  }
}
</style>